#ifndef FILAPROCESSO_H_INCLUDED
#define FILAPROCESSO_H_INCLUDED

#include "Processo.h"

typedef struct NoFila
{

   //Processo
   TProcesso  proc;

   //Ponteiro para proximo elemento da fila
   struct NoFila* prox;

}TNoFila;


typedef struct TFila
{
  TNoFila* ini;
  TNoFila* fim;

}TFila;


TNoFila* Fila_CriarNo(void)
{
   TNoFila *noFE = NULL;
   noFE = (TNoFila*) malloc( sizeof (TNoFila));
   noFE->prox = NULL;
   return noFE;
}

TFila * Fila_Criar()
{
    TFila * fila = (TFila*) malloc(sizeof(TFila));
    fila->ini= NULL;
    fila->fim = NULL;
    return fila;
}

void Fila_Inserir(TFila* header, TProcesso _pProcesso)
{
  TNoFila * no = Fila_CriarNo();
  no->proc = _pProcesso;

  if(header->fim)
    header->fim->prox=no;

  header->fim = no;

  if(!header->ini)
    header->ini = no;

}

int Fila_Vazia(TFila *header)
{
    return(!header->ini);
}

TProcesso Fila_Retirar(TFila* header)
{
    if(Fila_Vazia(header))
       exit(1);

    TNoFila* p    = header->ini;
    TProcesso pInfo = p->proc;

    header->ini = header->ini->prox;
    if(!header->ini)
       header->ini = NULL;

    free(p);

    return pInfo;
}

void Fila_Libera( TFila *header)
{
   if(!header)
   {
     printf("\n LiberaFilaEntrada -- header NULL \n");
     return;
   }

    while(!Fila_Vazia(header))
     Fila_Retirar(header);

   free(header);
}

void Fila_Imprimir(TFila* header)
{
     TFila* aux = Fila_Criar();
    while(!Fila_Vazia(header))
    {
        TProcesso noInfo = Fila_Retirar(header);
        Fila_Inserir(aux,noInfo);
        printf("################################ \n");
        printf("Processo Numero: %ld \n",noInfo.ID);
        printf("Criador: %s \n",noInfo.strCriador);
        printf("Comando: %s \n",noInfo.strComando);
        printf("################################ \n");
    }

    while(!Fila_Vazia(aux))
        Fila_Inserir(header,Fila_Retirar(aux));

}

void Fila_ImprimeUsuario(TFila* header)
{
    TFila* aux = Fila_Criar();
    while(!Fila_Vazia(header))
    {
        TProcesso processo = Fila_Retirar(header);
        Processo_Imprimir(&processo);

        while(!Fila_Vazia(header))
        {
            TProcesso nextProcesso = Fila_Retirar(header);

            if(ComparaString(&processo.strCriador,&nextProcesso.strCriador))
              Processo_Imprimir(&nextProcesso);
            else
              Fila_Inserir(aux,nextProcesso);
        }

       // LiberaProcesso(noInfo);
    }

    while(!Fila_Vazia(aux))
       Fila_Inserir(header,Fila_Retirar(aux));

    Fila_Libera(aux);
    Fila_ImprimeUsuario(header);
}


#endif // LISTAPROCESSO_H_INCLUDED
